From 5dd6e4d44c75a7754c45c7ab5373f352071dd69d Mon Sep 17 00:00:00 2001 From: "sos22@labyrinth.cl.cam.ac.uk" Date: Wed, 9 Jul 2003 15:28:07 +0000 Subject: [PATCH] bitkeeper revision 1.320 (3f0c3487S9CwVDQRe6TtSjZepJCw3w) Half of a way of getting /proc/dom0/vhd to return something sensible. --- xen/drivers/block/xen_block.c | 24 ++++++- xen/drivers/block/xen_segment.c | 2 +- xen/include/hypervisor-ifs/block.h | 2 + .../arch/xeno/drivers/block/xl_block.c | 2 + .../arch/xeno/drivers/block/xl_segment_proc.c | 70 +++++++++++++++++-- 5 files changed, 91 insertions(+), 9 deletions(-) diff --git a/xen/drivers/block/xen_block.c b/xen/drivers/block/xen_block.c index cef7c5e544..d1b8d855fd 100644 --- a/xen/drivers/block/xen_block.c +++ b/xen/drivers/block/xen_block.c @@ -102,6 +102,7 @@ static int do_block_io_op_domain(struct task_struct *p, int max_to_do); static void dispatch_rw_block_io(struct task_struct *p, int index); static void dispatch_probe_blk(struct task_struct *p, int index); static void dispatch_probe_seg(struct task_struct *p, int index); +static void dispatch_probe_seg_all(struct task_struct *p, int index); static void dispatch_debug_block_io(struct task_struct *p, int index); static void dispatch_create_segment(struct task_struct *p, int index); static void dispatch_delete_segment(struct task_struct *p, int index); @@ -387,6 +388,10 @@ static int do_block_io_op_domain(struct task_struct *p, int max_to_do) dispatch_probe_seg(p, i); break; + case XEN_BLOCK_PROBE_SEG_ALL: + dispatch_probe_seg_all(p, i); + break; + case XEN_BLOCK_DEBUG: dispatch_debug_block_io(p, i); break; @@ -566,7 +571,10 @@ static void dispatch_probe_blk(struct task_struct *p, int index) make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE_BLK, rc); } -static void dispatch_probe_seg(struct task_struct *p, int index) +static void dispatch_probe_seg_common(struct task_struct *p, + struct task_struct *target, + int type, + int index) { extern void xen_segment_probe(struct task_struct *, xen_disk_info_t *); @@ -589,12 +597,22 @@ static void dispatch_probe_seg(struct task_struct *p, int index) spin_unlock_irqrestore(&p->page_lock, flags); xdi = phys_to_virt(buffer); - xen_segment_probe(p, xdi); + xen_segment_probe(target, xdi); unlock_buffer(p, buffer, sizeof(xen_disk_info_t), 1); out: - make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE_SEG, rc); + make_response(p, blk_ring->ring[index].req.id, type, rc); +} + +static void dispatch_probe_seg(struct task_struct *p, int index) +{ + dispatch_probe_seg_common(p, p, XEN_BLOCK_PROBE_SEG, index); +} + +static void dispatch_probe_seg_all(struct task_struct *p, int index) +{ + dispatch_probe_seg_common(p, NULL, XEN_BLOCK_PROBE_SEG_ALL, index); } static void dispatch_rw_block_io(struct task_struct *p, int index) diff --git a/xen/drivers/block/xen_segment.c b/xen/drivers/block/xen_segment.c index 2f110423f0..c82ff39e05 100644 --- a/xen/drivers/block/xen_segment.c +++ b/xen/drivers/block/xen_segment.c @@ -162,7 +162,7 @@ void xen_segment_probe(struct task_struct *p, xen_disk_info_t *raw_xdi) for ( loop = 0; loop < XEN_MAX_SEGMENTS; loop++ ) { if ( (xsegments[loop].mode == XEN_SEGMENT_UNUSED) || - (xsegments[loop].domain != p->domain) ) + (p && xsegments[loop].domain != p->domain) ) continue; device = MK_VIRTUAL_XENDEV(xsegments[loop].segment_number); diff --git a/xen/include/hypervisor-ifs/block.h b/xen/include/hypervisor-ifs/block.h index f5cf635afc..f269e57bd1 100644 --- a/xen/include/hypervisor-ifs/block.h +++ b/xen/include/hypervisor-ifs/block.h @@ -50,6 +50,8 @@ #define XEN_BLOCK_PHYSDEV_GRANT 10 /* grant access to range of disk blocks */ #define XEN_BLOCK_PHYSDEV_PROBE 11 /* probe for a domain's physdev accesses */ +#define XEN_BLOCK_PROBE_SEG_ALL 12 /* prove for every domain's segments, + not just ours. */ /* NB. Ring size must be small enough for sizeof(blk_ring_t) <= PAGE_SIZE. */ #define BLK_RING_SIZE 64 diff --git a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c index 7bcf3297b1..dbaffb76d9 100644 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c @@ -311,6 +311,7 @@ static int hypervisor_request(unsigned long id, case XEN_BLOCK_PHYSDEV_PROBE: case XEN_BLOCK_PROBE_BLK: case XEN_BLOCK_PROBE_SEG: + case XEN_BLOCK_PROBE_SEG_ALL: if ( RING_FULL ) return 1; phys_device = (kdev_t) 0; sector_number = 0; @@ -479,6 +480,7 @@ static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs) case XEN_BLOCK_SEG_CREATE: case XEN_BLOCK_SEG_DELETE: case XEN_BLOCK_PROBE_SEG: + case XEN_BLOCK_PROBE_SEG_ALL: case XEN_BLOCK_PROBE_BLK: case XEN_BLOCK_PHYSDEV_GRANT: case XEN_BLOCK_PHYSDEV_PROBE: diff --git a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c index 805f7336ec..df65e8b046 100644 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c @@ -7,17 +7,70 @@ #include "xl_block.h" #include #include +#include static struct proc_dir_entry *vhd; extern unsigned short xldev_to_physdev(kdev_t xldev); -static int proc_read_vhd(char *page, char **start, off_t off, - int count, int *eof, void *data) +static void *proc_vhd_next(struct seq_file *s, void *v, loff_t *pos) { + xen_disk_info_t *data; + + if ( pos != NULL ) + ++(*pos); + + data = v; + return data->count-- ? NULL : v; +} + +static void *proc_vhd_start(struct seq_file *s, loff_t *ppos) +{ + loff_t pos = *ppos; + xen_disk_info_t *data; + + data = kmalloc(sizeof(*data), GFP_KERNEL); + xenolinux_control_msg(XEN_BLOCK_PROBE_SEG_ALL, (char *)data, sizeof(*data)); + data->count -= pos; + + if (data->count > 0) + return data; + + kfree(data); + return NULL; +} + +static int proc_vhd_show(struct seq_file *s, void *v) +{ + xen_disk_info_t *data = v; + + seq_printf (s, + "%4x %4x %lx\n", + data->disks[data->count - 1].device, + data->disks[data->count - 1].type, + data->disks[data->count - 1].capacity); + return 0; } +static void proc_vhd_stop(struct seq_file *s, void *v) +{ + kfree(v); +} + +static struct seq_operations proc_vhd_op = { + .start = proc_vhd_start, + .next = proc_vhd_next, + .show = proc_vhd_show, + .stop = proc_vhd_stop +}; + +static int proc_open_vhd(struct inode *inode, struct file *file) +{ + return seq_open(file, &proc_vhd_op); +} + + #define isdelim(c) \ (c==' '||c==','||c=='\n'||c=='\r'||c=='\t'||c==':'||c=='('||c==')' ? 1 : 0) @@ -72,7 +125,7 @@ unsigned long to_number(char *string) /* atoi */ } static int proc_write_vhd(struct file *file, const char *buffer, - unsigned long count, void *data) + size_t count, loff_t *offp) { char *local = kmalloc((count + 1) * sizeof(char), GFP_KERNEL); char *string; @@ -226,6 +279,14 @@ static int proc_write_vhd(struct file *file, const char *buffer, return res; } +static struct file_operations proc_vhd_operations = { + open: proc_open_vhd, + read: seq_read, + llseek: seq_lseek, + release: seq_release, + write: proc_write_vhd +}; + /******************************************************************/ int __init xlseg_proc_init(void) @@ -236,8 +297,7 @@ int __init xlseg_proc_init(void) panic ("xlseg_init: unable to create vhd proc entry\n"); } vhd->data = NULL; - vhd->read_proc = proc_read_vhd; - vhd->write_proc = proc_write_vhd; + vhd->proc_fops = &proc_vhd_operations; vhd->owner = THIS_MODULE; printk(KERN_ALERT "XenoLinux Virtual Disk Device Monitor installed\n"); -- 2.30.2